package cn.buk.qms.web;

import cn.buk.common.JsonResult;
import cn.buk.common.dto.CommonDto;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.tms.dto.CustomerServiceTemplateDto;
import cn.buk.tms.dto.EntBalanceDto;
import cn.buk.tms.sc.SearchCustomerCriteria;
import cn.buk.qms.service.CustomerService;
import cn.buk.qms.service.EnterpriseService;
import cn.buk.qms.service.UserService;
import cn.buk.tms.common.dto.CustomerAvCountInfoDto;
import cn.buk.tms.common.dto.CustomerDiscountInfoDto;
import cn.buk.tms.common.dto.CustomerDto;
import cn.buk.tms.dto.*;
import cn.buk.tms.entity.misc.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;

/**
 * 客户信息操作
 * @author yfdai
 */
@RestController
public class CustomerController extends BaseController {

  @Autowired
  public CustomerController(UserService userService,
                              EnterpriseService enterpriseService,
                            CustomerService customerService) {
    this.userService = userService;
    this.enterpriseService = enterpriseService;
    this.customerService = customerService;
  }

  private final UserService userService;

  private final EnterpriseService enterpriseService;

  private final CustomerService customerService;

  @RequestMapping("/customers")
  public CommonDto<CustomerDto> searchCustomers(HttpServletRequest request,
                                                @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    List<CustomerDto> customers = userService.searchCustomers(enterpriseId, userId, sc);

    CommonDto<CustomerDto> commonDto = new CommonDto<>();
    commonDto.setDataList(customers);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  @RequestMapping("/customer/{id}")
  public CustomerDetailDto searchCustomers(HttpServletRequest request,
                                           @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);

    return userService.getCustomerById(enterpriseId, id);
  }

  /**
   * 获取为客户设置的优惠信息（酒店、用车、登机牌办理）
   */
  @GetMapping("/customer/{id}/discount")
  public CustomerDiscountInfoDto searchCustomerDiscountInfo(HttpServletRequest request,
                                                            @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.getCustomerDiscountInfo(enterpriseId, id);
  }

  /**
   * 保存为客户设置的优惠信息（酒店、用车、登机牌办理）
   */
  @PostMapping("/customer/{id}/discount")
  public JsonResult saveCustomerDiscountInfo(HttpServletRequest request,
                                             @PathVariable("id") int id,
                                             @RequestParam("hotelDiscount") final int hotelDiscount,
                                             @RequestParam("carDiscount") final int carDiscount,
                                             @RequestParam("boardingCardDiscount") final int boardingCardDiscount,
                                             @RequestParam("domFlightDiscount") final int domFlightDiscount,
                                             @RequestParam("intlFlightDiscount") final int intlFlightDiscount
  ) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.saveCustomerDiscountInfo(enterpriseId, id, hotelDiscount, carDiscount, boardingCardDiscount, domFlightDiscount, intlFlightDiscount);
  }

  /**
   * 获取为客户设置的机票优惠信息
   */
  @GetMapping("/customer/{id}/flightDiscounts")
  public List<CustomerFlightDiscountDto> searchCustomerFlightDiscounts(HttpServletRequest request,
                                                                       @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.searchCustomerFlightDiscounts(enterpriseId, id);
  }

  /**
   * 保存为客户设置的机票优惠信息
   * @param mode 0-新增，4-删除
   */
  @PostMapping("/customer/{id}/flightDiscount")
  public JsonResult saveCustomerFlightDiscount(HttpServletRequest request,
                                               @PathVariable("id") int customerId,
                                               @RequestParam("policyCode") String policyCode,
                                               @RequestParam(value = "commissionRateRetained", defaultValue = "0") int commRateRetained,
                                               @RequestParam("mode") int mode
  ) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.saveCustomerFlightDiscount(enterpriseId, customerId, policyCode, commRateRetained, mode);
  }

  /**
   * 待处理客户
   */
  @RequestMapping("/customer/todos")
  public List<Enterprise> searchCustomerTodos(HttpServletRequest request) {
    final int enterpriseId = getEnterpriseId(request);
    return userService.searchCustomerTodo(enterpriseId);
  }

  /**
   * 查找客户详情
   */
  @RequestMapping("/customer-details")
  public CommonDto<CustomerDetailDto> searchCustomerDetails(HttpServletRequest request,
                                                            @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    List<CustomerDetailDto> customers = userService.searchCustomerDetails(enterpriseId, getUserId(request), sc);

    CommonDto<CustomerDetailDto> commonDto = new CommonDto<>();
    commonDto.setDataList(customers);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 创建下级的差旅企业账号, 创建客户
   */
  @PostMapping(value = "/customer", consumes = "application/json")
  public JsonResult createTmcUser(HttpServletRequest request,
                                  @RequestBody Customer c) {
    if (c == null || c.getVipName().length() < 1) {
      return JsonResult.createJsonResult(-1, "公司名称必需填写");
    }

    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);
    final String username = getUsername(request);

    JsonResult jsonResult = new JsonResult();
    jsonResult.setStatus("ER");

    if (c.getCustomerCode() != null && c.getCustomerCode().trim().length() == 0) {
      c.setCustomerCode(null);
    }

    int retCode = userService.createOrUpdateCustomer(enterpriseId, userId, username, c);

    if (retCode > 0) {
      jsonResult.setErrcode(0);
      jsonResult.setStatus("OK");
      jsonResult.setReturnCode(retCode);
    } else {
      retCode = Math.abs(retCode);
      jsonResult.setErrcode(retCode);
      if (retCode == 10005) {
        jsonResult.setErrmsg("用户名已存在");
      } else {
        String remark = "保存时出现错误, 请检查是否重复";
        jsonResult.setErrmsg(remark);
      }
    }

    return jsonResult;
  }

  /**
   * 根据已有的企业生成对应的客户信息
   */
  @RequestMapping(value = "/customer/enterprise/{id}")
  public JsonResult generateNewCustomer(HttpServletRequest request,
                                        @PathVariable("id") final int customerEnterpriseId) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.createCustomerByEnterprise(enterpriseId, customerEnterpriseId);
  }

  /**
   * 查找指定企业客户的部门信息
   */
  @RequestMapping("/customer/{customerId}/departments")
  public CommonDto<CustomerDepartment> searchDepartments(HttpServletRequest request,
                                                         @PathVariable("customerId") int customerId) {
    final int enterpriseId = getEnterpriseId(request);

    List<CustomerDepartment> departments = enterpriseService
            .searchDepartmentsByCustomer(enterpriseId, customerId);

    CommonDto<CustomerDepartment> commonDto = new CommonDto<>();
    commonDto.setDataList(departments);

    return commonDto;
  }

  /**
   * 查找企业客户的授信等信息
   */
  @RequestMapping("/customerBalances")
  public CommonDto<EntBalanceDto> searchCustomerBalances(HttpServletRequest request,
                                                         @ModelAttribute("sc") SearchCustomerCriteria sc) {
    List<EntBalanceDto> balances = enterpriseService
            .searchCustomerBalances(getEnterpriseId(request), sc);

    CommonDto<EntBalanceDto> commonDto = new CommonDto<>();
    commonDto.setDataList(balances);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 企业客户的交易记录
   */
  @RequestMapping("/customer/{eid}/trans")
  public CommonDto<AmountHistory> searchCustomerTrans(HttpServletRequest request,
                                                      @PathVariable("eid") int customerEnterpriseId,
                                                      @ModelAttribute("sc") CommonSearchCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    sc.setEnterpriseId(customerEnterpriseId);

    CommonDto<AmountHistory> commonDto = new CommonDto<>();
    List<AmountHistory> histories = userService.searchTransactionHistory(enterpriseId, sc);

    commonDto.setDataList(histories);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 查找企业账单注释
   */
  @RequestMapping("/customer/notes")
  public CommonDto<CustomerNote> searchCustomerNotes(HttpServletRequest request,
                                                     @ModelAttribute("sc") CommonSearchCriteria sc,
                                                     @RequestParam(value = "customerId", defaultValue = "0") int customerId,
                                                     @RequestParam(value = "noteType", defaultValue = "0") int noteType
  ) {
    final int enterpriseId = getEnterpriseId(request);

    List<CustomerNote> dtos = enterpriseService
            .searchCustomerNotes(enterpriseId, sc, customerId, noteType);

    CommonDto<CustomerNote> commonDto = new CommonDto<>();
    commonDto.setDataList(dtos);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }


  /**
   * 查找某企业的指定类型的账单注释
   */
  @RequestMapping("/customer/{customerId}/notes")
  public List<CustomerNote> searchCustomerNotesByType(HttpServletRequest request,
                                                      @PathVariable("customerId") int customerId,
                                                      @RequestParam(value = "noteType", defaultValue = "0") int noteType
  ) {
    return enterpriseService.searchCustomerNotesByType(getEnterpriseId(request), customerId, noteType);
  }


  /**
   * 新建企业账单注释
   */
  @PostMapping(value = "/customer/note/create")
  public JsonResult createCustomerNote(HttpServletRequest request,
                                       @RequestParam("customerId") int customerId,
                                       @RequestParam("noteType") int noteType,
                                       @RequestParam("name") String name
  ) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.createCustomerNote(enterpriseId, customerId, noteType, name);
  }


  /**
   * 删除企业账单注释
   */
  @PostMapping(value = "/customer/note/{id}/delete")
  public JsonResult deleteCustomerNoteById(HttpServletRequest request,
                                           @PathVariable("id") int id
  ) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.deleteCustomerNoteById(enterpriseId, id);
  }


  /**
   * 根据客人的名字查找可能所属的公司客户
   */
  @RequestMapping("/possibleCustomers")
  public String[] searchPossibleCustomers(HttpServletRequest request,
                                          @RequestBody PassengerDto[] names) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.searchPossibleCustomers(enterpriseId, names);
  }


  /**
   * 查找企业客户的部门信息
   */
  @RequestMapping("/customers/departments")
  public CommonDto<CustomerDepartmentDto> searchDepartments(HttpServletRequest request,
                                                         @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    List<CustomerDepartmentDto> departments = enterpriseService.searchCustomerDepartments(enterpriseId, sc);

    CommonDto<CustomerDepartmentDto> commonDto = new CommonDto<>();
    commonDto.setDataList(departments);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 获取企业客户的部门信息
   * @param id 部门id
   */
  @GetMapping("/customer/department/{id}")
  public CustomerDepartmentDto getDepartmentById(HttpServletRequest request,
                                                         @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.getCustomerDepartmentById(enterpriseId, id);
  }

  /**
   * 创建或修改企业客户的部门信息
   */
  @PostMapping(value = "/customer/department", consumes = "application/json")
  public JsonResult createCustomerDepartment(HttpServletRequest request,
                                     @RequestBody CustomerDepartment dto) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    return enterpriseService.saveCustomerDepartment(enterpriseId, userId, dto);
  }

  /**
   * 创建或删除企业客户的职位信息
   */
  @PostMapping(value = "/customer/{customerId}/position", consumes = "application/json")
  public JsonResult createCustomerPosition(HttpServletRequest request,
                                             @PathVariable("customerId") int customerId,
                                             @RequestBody CustomerPosition dto) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    Customer c = new Customer();
    c.setId(customerId);

    dto.setCustomer(c);

    return enterpriseService.saveCustomerPosition(enterpriseId, userId, dto);
  }

  /**
   * 查找企业客户的员工级别
   */
  @RequestMapping("/customer/{customerId}/positions")
  public CommonDto<CustomerPositionDto> searchCustomerPositions(HttpServletRequest request,
                                                         @PathVariable("customerId") int customerId,
                                                         @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    sc.setCustomerId(customerId);

    List<CustomerPositionDto> departments = enterpriseService.searchCustomerPositions(enterpriseId, sc);

    CommonDto<CustomerPositionDto> commonDto = new CommonDto<>();
    commonDto.setDataList(departments);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }


  /**
   * 查找企业客户的差旅地区分类
   */
  @RequestMapping("/customer/{customerId}/zones")
  public CommonDto<CustomerTravelZoneDto> searchCustomerTravelZones(HttpServletRequest request,
                                                               @PathVariable("customerId") int customerId,
                                                               @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    sc.setCustomerId(customerId);

    List<CustomerTravelZoneDto> zones = customerService.searchCustomerTravelZones(enterpriseId, sc);

    CommonDto<CustomerTravelZoneDto> commonDto = new CommonDto<>();
    commonDto.setDataList(zones);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 创建/删除企业客户的差旅地区分类
   */
  @PostMapping("/customer/{customerId}/zone")
  public JsonResult saveCustomerTravelZone(HttpServletRequest request,
                                                                 @PathVariable("customerId") int customerId,
                                                                 @RequestParam("zoneId") int zoneId,
                                                                 @RequestParam("cityId") int cityId,
                                            @RequestParam("mode") int mode) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    return customerService.saveCustomerTravelZone(enterpriseId, username, customerId, zoneId, cityId, mode);
  }

  /**
   * 查找企业客户的登录用户信息
   */
  @RequestMapping("/customer/{customerId}/loginInfos")
  public CommonDto<LoginInfoDto> searchCustomerLoginInfos(HttpServletRequest request,
                                                     @PathVariable("customerId") int customerId,
                                                     @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    sc.setCustomerId(customerId);

    List<LoginInfoDto> dtos = customerService.searchCustomerLoginInfos(enterpriseId, sc);

    CommonDto<LoginInfoDto> commonDto = new CommonDto<>();
    commonDto.setDataList(dtos);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 保存企业客户的部门差旅审批人
   */
  @PostMapping("/customer/{customerId}/department/{departmentId}/approver")
  public JsonResult saveCustomerDepartmentApprover(HttpServletRequest request,
                                                          @PathVariable("customerId") int customerId,
                                                          @PathVariable("departmentId") int departmentId,
                                                          @RequestParam("userId") int approverId,
                                                          @RequestParam("roleType") int roleType
                                                   ) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    return customerService.saveCustomerDepartmentApprover(enterpriseId, userId, customerId, departmentId, approverId, roleType);
  }

  /**
   * 删除企业客户的部门差旅审批人
   */
  @DeleteMapping(value = "/customer/department/approver/{id}")
  public JsonResult deleteCustomerDepartmentApprover(HttpServletRequest request,
                                                   @PathVariable("id") int approverId) {
    final int userId = getUserId(request);

    return customerService.deleteCustomerDepartmentApprover(userId, approverId);
  }

  /**
   * 修改企业客户的短信发送模式
   */
  @PostMapping(value = "/customer/{customerId}/smsMode")
  public JsonResult saveCustomerSmsMode(HttpServletRequest request,
                                                     @PathVariable("customerId") int customerId,
                                          @RequestParam("smsMode") int smsMode
                                          ) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    return customerService.saveCustomerSmsMode(enterpriseId, userId, customerId, smsMode);
  }

  /**
   * 获取指定客户适用的服务费模板
   */
  @GetMapping("/customer/{id}/serviceTemplate")
  public CustomerServiceTemplateDto searchServiceTemplateByCustomer(HttpServletRequest request,
                                                                    @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);
    Optional<CustomerServiceTemplateDto> tpl = enterpriseService.searchServiceTemplateByCustomer(enterpriseId, id);

    return tpl.orElse(null);
  }

  /**
   * 获取为客户设置的航班查询次数信息
   */
  @GetMapping("/customer/{id}/avCountInfo")
  public CustomerAvCountInfoDto searchCustomerAvCountInfo(HttpServletRequest request,
                                                          @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.getCustomerAvCountInfo(enterpriseId, id);
  }

  /**
   * 保存为客户设置的航班查询控制信息
   */
  @PostMapping("/customer/{id}/avCountInfo")
  public JsonResult saveCustomerAvCountInfo(HttpServletRequest request,
                                             @PathVariable("id") int id,
                                             @RequestParam("maxTotal") final int maxTotal,
                                             @RequestParam("maxMonthly") final int maxMonthly
  ) {
    final int enterpriseId = getEnterpriseId(request);
    return enterpriseService.saveCustomerAvCountInfo(enterpriseId, id, maxTotal, maxMonthly);
  }
}
